home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / language / embedded / mcu / asembler.arc / DO9.C < prev    next >
Text File  |  1987-12-09  |  12KB  |  603 lines

  1. /*
  2.  *      MC6809 specific processing
  3.  */
  4.  
  5. #define PAGE2    0x10
  6. #define PAGE3    0x11
  7. #define IPBYTE    0x9F    /* extended indirect postbyte */
  8. #define SWI     0x3F
  9.  
  10. /* register names */
  11.  
  12. #define RD    0
  13. #define RX    1
  14. #define RY    2
  15. #define RU    3
  16. #define RS    4
  17. #define RPC    5
  18. #define RA    8
  19. #define RB    9
  20. #define RCC    10
  21. #define RDP    11
  22. #define RPCR    12
  23.  
  24. /* convert tfr/exg reg number into psh/pul format */
  25. int     regs[] = { 6,16,32,64,64,128,0,0,2,4,1,8,0};
  26. int     rcycl[]= { 2,2, 2, 2, 2, 2,  0,0,1,1,1,1,0};
  27.  
  28. /* addressing modes */
  29. #define IMMED   0       /* immediate */
  30. #define IND     1       /* indexed */
  31. #define INDIR   2       /* indirect */
  32. #define OTHER   3       /* NOTA */
  33.  
  34. /*
  35.  *      localinit --- machine specific initialization
  36.  */
  37. localinit()
  38. {
  39. }
  40.  
  41. /*
  42.  *      do_op --- process mnemonic
  43.  *
  44.  *    Called with the base opcode and it's class. Optr points to
  45.  *    the beginning of the operand field.
  46.  */
  47. do_op(opcode,class)
  48. int opcode;    /* base opcode */
  49. int class;    /* mnemonic class */
  50. {
  51.     int     dist;   /* relative branch distance */
  52.     int     src,dst;/* source and destination registers */
  53.     int     pbyte;  /* postbyte value */
  54.     int     amode;  /* indicated addressing mode */
  55.     int    j;
  56.  
  57.     amode = set_mode();     /* pickup indicated addressing mode */
  58.  
  59.     switch(class){
  60.         case INH:                       /* inherent addressing */
  61.             emit(opcode);
  62.             return;
  63.         case GEN:                       /* general addressing */
  64.             do_gen(opcode,amode);
  65.             return;
  66.         case IMM:                       /* immediate addressing */
  67.             if( amode != IMMED ){
  68.                 error("Immediate Operand Required");
  69.                 return;
  70.                 }
  71.             Optr++;
  72.             eval();
  73.             emit(opcode);
  74.             emit(lobyte(Result));
  75.             return;
  76.         case REL:                       /* short relative branches */
  77.             eval();
  78.             dist = Result - (Pc+2);
  79.             emit(opcode);
  80.             if( (dist >127 || dist <-128) && Pass==2){
  81.                 error("Branch out of Range");
  82.                 emit(lobyte(-2));
  83.                 return;
  84.                 }
  85.             emit(lobyte(dist));
  86.             return;
  87.         case P2REL:                     /* long relative branches */
  88.             eval();
  89.             dist = Result - (Pc+4);
  90.             emit(PAGE2);
  91.             emit(opcode);
  92.             eword(dist);
  93.             return;
  94.         case P1REL:                     /* lbra and lbsr */
  95.             if( amode == IMMED)
  96.                 Optr++; /* kludge for C compiler */
  97.             eval();
  98.             dist = Result - (Pc+3);
  99.             emit(opcode);
  100.             eword(dist);
  101.             return;
  102.         case NOIMM:
  103.             if( amode == IMMED ){
  104.                 error("Immediate Addressing Illegal");
  105.                 return;
  106.                 }
  107.             do_gen(opcode,amode);
  108.             return;
  109.         case P2GEN:
  110.             emit(PAGE2);
  111.             if( amode == IMMED ){
  112.                 emit(opcode);
  113.                 Optr++;
  114.                 eval();
  115.                 eword(Result);
  116.                 return;
  117.                 }
  118.             do_gen(opcode,amode);
  119.             return;
  120.         case P3GEN:
  121.             emit(PAGE3);
  122.             if( amode == IMMED ){
  123.                 emit(opcode);
  124.                 Optr++;
  125.                 eval();
  126.                 eword(Result);
  127.                 return;
  128.                 }
  129.             do_gen(opcode,amode);
  130.             return;
  131.         case RTOR:                      /* tfr and exg */
  132.             emit(opcode);
  133.             src = regnum();
  134.             while(alpha(*Optr))Optr++;
  135.             if(src==ERR){
  136.                 error("Register Name Required");
  137.                 emit(0);
  138.                 return;
  139.                 }
  140.             if(*Optr++ != ','){
  141.                 error("Missing ,");
  142.                 emit(0);
  143.                 return;
  144.                 }
  145.             dst = regnum();
  146.             while(alpha(*Optr))Optr++;
  147.             if(dst==ERR){
  148.                 error("Register Name Required");
  149.                 emit(0);
  150.                 return;
  151.                 }
  152.             if( src==RPCR || dst==RPCR){
  153.                 error("PCR illegal here");
  154.                 emit(0);
  155.                 return;
  156.                 }
  157.             if( (src <=5 && dst >=8) ||
  158.                 (src >=8 && dst <=5)){
  159.                 error("Register Size Mismatch");
  160.                 emit(0);
  161.                 return;
  162.                 }
  163.             emit( (src<<4)+dst );
  164.             return;
  165.         case INDEXED:                   /* indexed addressing only */
  166.             if( *Optr == '#'){
  167.                 Optr++;         /* kludge city */
  168.                 amode = IND;
  169.                 }
  170.             if( amode != IND ){
  171.                 error("Indexed Addressing Required");
  172.                 return;
  173.                 }
  174.             do_indexed(opcode);
  175.             return;
  176.         case RLIST:                     /* pushes and pulls */
  177.             if(*Operand == EOS){
  178.                 error("Register List Required");
  179.                 return;
  180.                 }
  181.             emit(opcode);
  182.             pbyte = 0;
  183.             do{
  184.                 j = regnum();
  185.                 if( j == ERR || j==RPCR)
  186.                     error("Illegal Register Name");
  187.                 else if(j==RS && (opcode==52))
  188.                     error("Can't Push S on S");
  189.                 else if(j==RU && (opcode==54))
  190.                     error("Can't Push U on U");
  191.                 else if(j==RS && (opcode==53))
  192.                     error("Can't Pull S from S");
  193.                 else if(j==RU && (opcode==55))
  194.                     error("Can't Pull U from U");
  195.                 else{
  196.                     pbyte |= regs[j];
  197.                     Cycles += rcycl[j];
  198.                     }
  199.                 while(*Optr != EOS && alpha(*Optr))Optr++;
  200.             }while( *Optr++ == ',' );
  201.             emit(lobyte(pbyte));
  202.             return;
  203.         case P2NOIMM:
  204.             if( amode == IMMED )
  205.                 error("Immediate Addressing Illegal");
  206.             else{
  207.                 emit(PAGE2);
  208.                 do_gen(opcode,amode);
  209.                 }
  210.             return;
  211.         case P2INH:                     /* Page 2 inherent */
  212.             emit(PAGE2);
  213.             emit(opcode);
  214.             return;
  215.         case P3INH:                     /* Page 3 inherent */
  216.             emit(PAGE3);
  217.             emit(opcode);
  218.             return;
  219.         case LONGIMM:
  220.             if( amode == IMMED ){
  221.                 emit(opcode);
  222.                 Optr++;
  223.                 eval();
  224.                 eword(Result);
  225.                 }
  226.             else
  227.                 do_gen(opcode,amode);
  228.             return;
  229.         case GRP2:
  230.             if( amode == IND ){
  231.                 do_indexed(opcode+0x60);
  232.                 return;
  233.                 }
  234.             else if( amode == INDIR){
  235.                 Optr++;
  236.                 emit(opcode + 0x60);
  237.                 emit(IPBYTE);
  238.                 eval();
  239.                 eword(Result);
  240.                 Cycles += 7;
  241.                 if(*Optr == ']'){
  242.                     Optr++;
  243.                     return;
  244.                     }
  245.                 error("Missing ']'");
  246.                 return;
  247.                 }
  248.             eval();
  249.             if(Force_word){
  250.                 emit(opcode+0x70);
  251.                 eword(Result);
  252.                 Cycles += 3;
  253.                 return;
  254.                 }
  255.             if(Force_byte){
  256.                 emit(opcode);
  257.                 emit(lobyte(Result));
  258.                 Cycles += 2;
  259.                 return;
  260.                 }
  261.             if(Result>=0 && Result <=0xFF){
  262.                 emit(opcode);
  263.                 emit(lobyte(Result));
  264.                 Cycles += 2;
  265.                 return;
  266.                 }
  267.             else {
  268.                 emit(opcode+0x70);
  269.                 eword(Result);
  270.                 Cycles += 3;
  271.                 return;
  272.                 }
  273.         case SYS:                       /* system call */
  274.             emit(SWI);
  275.             eval();
  276.             emit(lobyte(Result));
  277.             return;
  278.         default:
  279.             fatal("Error in Mnemonic table");
  280.         }
  281. }
  282.  
  283.  
  284. /*
  285.  *      do_gen --- process general addressing mode stuff
  286.  */
  287. do_gen(op,mode)
  288. int     op;
  289. int     mode;
  290. {
  291.     if( mode == IMMED){
  292.         Optr++;
  293.         emit(op);
  294.         eval();
  295.         emit(lobyte(Result));
  296.         return;
  297.         }
  298.     else if( mode == IND ){
  299.         do_indexed(op+0x20);
  300.         return;
  301.         }
  302.     else if( mode == INDIR){
  303.         Optr++;
  304.         emit(op+0x20);
  305.         emit(IPBYTE);
  306.         eval();
  307.         eword(Result);
  308.         Cycles += 7;
  309.         if(*Optr == ']'){
  310.             Optr++;
  311.             return;
  312.             }
  313.         error("Missing ']'");
  314.         return;
  315.         }
  316.     else if( mode == OTHER){
  317.         eval();
  318.         if(Force_word){
  319.             emit(op+0x30);
  320.             eword(Result);
  321.             Cycles += 3;
  322.             return;
  323.             }
  324.         if(Force_byte){
  325.             emit(op+0x10);
  326.             emit(lobyte(Result));
  327.             Cycles += 2;
  328.             return;
  329.             }
  330.         if(Result>=0 && Result <=0xFF){
  331.             emit(op+0x10);
  332.             emit(lobyte(Result));
  333.             Cycles += 2;
  334.             return;
  335.             }
  336.         else {
  337.             emit(op+0x30);
  338.             eword(Result);
  339.             Cycles += 3;
  340.             return;
  341.             }
  342.         }
  343.     else {
  344.         error("Unknown Addressing Mode");
  345.         return;
  346.         }
  347. }
  348.  
  349. /*
  350.  *      do_indexed --- handle all wierd stuff for indexed addressing
  351.  */
  352. do_indexed(op)
  353. int op;
  354. {
  355.     int     pbyte;
  356.     int     j,k;
  357.     int     predec,pstinc;
  358.  
  359.     Cycles += 2;    /* indexed is always 2+ base cycle count */
  360.     predec=0;
  361.     pstinc=0;
  362.     pbyte=128;
  363.     emit(op);
  364.     if(*Optr=='['){
  365.         pbyte |= 0x10;    /* set indirect bit */
  366.         Optr++;
  367.         if( !any((char)']',Optr))
  368.             error("Missing ']'");
  369.         Cycles += 3;    /* indirection takes this much longer */
  370.         }
  371.     j=regnum();
  372.     if(j==RA){
  373.         Cycles++;
  374.         abd_index(pbyte+6);
  375.         return;
  376.         }
  377.     if(j==RB){
  378.         Cycles++;
  379.         abd_index(pbyte+5);
  380.         return;
  381.         }
  382.     if(j==RD){
  383.         Cycles += 4;
  384.         abd_index(pbyte+11);
  385.         return;
  386.         }
  387.     eval();
  388.     Optr++;
  389.     while(*Optr=='-'){
  390.         predec++;
  391.         Optr++;
  392.         }
  393.     j=regnum();
  394.     while( alpha(*Optr) )Optr++;
  395.     while(*Optr=='+'){
  396.         pstinc++;
  397.         Optr++;
  398.         }
  399.     if(j==RPC || j==RPCR){
  400.         if( pstinc || predec ){
  401.             error("Auto Inc/Dec Illegal on PC");
  402.             return;
  403.             }
  404.         if(j==RPC){
  405.             if(Force_word){
  406.                 emit(pbyte+13);
  407.                 eword(Result);
  408.                 Cycles += 5;
  409.                 return;
  410.                 }
  411.             if(Force_byte){
  412.                 emit(pbyte+12);
  413.                 emit(lobyte(Result));
  414.                 Cycles++;
  415.                 return;
  416.                 }
  417.             if(Result>=-128 && Result <=127){
  418.                 emit(pbyte+12);
  419.                 emit(lobyte(Result));
  420.                 Cycles++;
  421.                 return;
  422.                 }
  423.             else {
  424.                 emit(pbyte+13);
  425.                 eword(Result);
  426.                 Cycles += 5;
  427.                 return;
  428.                 }
  429.             }
  430.         /* PCR addressing */
  431.         if(Force_word){
  432.             emit(pbyte+13);
  433.             eword(Result-(Pc+2));
  434.             Cycles += 5;
  435.             return;
  436.             }
  437.         if(Force_byte){
  438.             emit(pbyte+12);
  439.             emit(lobyte(Result-(Pc+1)));
  440.             Cycles++;
  441.             return;
  442.             }
  443.         k=Result-(Pc+2);
  444.         if( k >= -128 && k <= 127){
  445.             emit(pbyte+12);
  446.             emit(lobyte(Result-(Pc+1)));
  447.             Cycles++;
  448.             return;
  449.             }
  450.         else{
  451.             emit(pbyte+13);
  452.             eword(Result-(Pc+2));
  453.             Cycles += 5;
  454.             return;
  455.             }
  456.         }
  457.     if(predec || pstinc){
  458.         if(Result != 0){
  459.             error("Offset must be Zero");
  460.             return;
  461.             }
  462.         if(predec>2 || pstinc>2){
  463.             error("Auto Inc/Dec by 1 or 2 only");
  464.             return;
  465.             }
  466.         if((predec==1 && (pbyte&0x10) != 0) ||
  467.            (pstinc==1 && (pbyte&0x10) != 0)){
  468.             error("No Auto Inc/Dec by 1 for Indirect");
  469.             return;
  470.             }
  471.         if(predec && pstinc){
  472.             error("Can't do both!");
  473.             return;
  474.             }
  475.         if(predec)
  476.             pbyte += predec+1;
  477.         if(pstinc)
  478.             pbyte += pstinc-1;
  479.         pbyte += rtype(j);
  480.         emit(pbyte);
  481.         Cycles += 1 + predec + pstinc;
  482.         return;
  483.         }
  484.     pbyte += rtype(j);
  485.     if(Force_word){
  486.         emit(pbyte+0x09);
  487.         eword(Result);
  488.         Cycles += 4;
  489.         return;
  490.         }
  491.     if(Force_byte){
  492.         emit(pbyte+0x08);
  493.         emit(lobyte(Result));
  494.         Cycles++;
  495.         return;
  496.         }
  497.     if(Result==0){
  498.         emit(pbyte+0x04);
  499.         return;
  500.         }
  501.     if((Result >= -16) && (Result <= 15) && ((pbyte&16)==0)){
  502.         pbyte &= 127;
  503.         pbyte += Result&31;
  504.         emit(pbyte);
  505.         Cycles++;
  506.         return;
  507.         }
  508.     if(Result >= -128 && Result <= 127){
  509.         emit(pbyte+0x08);
  510.         emit(lobyte(Result));
  511.         Cycles++;
  512.         return;
  513.         }
  514.     emit(pbyte+0x09);
  515.     eword(Result);
  516.     Cycles += 4;
  517.     return;
  518. }
  519.  
  520.  
  521. /*
  522.  *      abd_index --- a,b or d indexed
  523.  */
  524.  
  525. abd_index(pbyte)
  526. int pbyte;
  527. {
  528.     int     k;
  529.  
  530.     Optr += 2;
  531.     k=regnum();
  532.     pbyte += rtype(k);
  533.     emit(pbyte);
  534.     return;
  535. }
  536.  
  537. /*
  538.  *      rtype --- return register type in post-byte format
  539.  */
  540. rtype(r)
  541. int r;
  542. {
  543.     switch(r){
  544.     case RX:        return(0x00);
  545.     case RY:        return(0x20);
  546.     case RU:        return(0x40);
  547.     case RS:        return(0x60);
  548.         }
  549.     error("Illegal Register for Indexed");
  550.     return(0);
  551. }
  552.  
  553. /*
  554.  *      set_mode --- determine addressing mode from operand field
  555.  */
  556. set_mode()
  557. {
  558.     register char *p;
  559.  
  560.     if( *Operand == '#' )
  561.         return(IMMED);          /* immediate addressing */
  562.     p = Operand;
  563.     while( *p != EOS && *p != BLANK && *p != TAB){/* any , before break */
  564.         if( *p == ',')
  565.             return(IND);    /* indexed addressing */
  566.         p++;
  567.         }
  568.     if( *Operand == '[')
  569.         return(INDIR);          /* indirect addressing */
  570.     return(OTHER);                  /* NOTA */
  571. }
  572.  
  573. /*
  574.  *      regnum --- return register number of *Optr
  575.  */
  576. regnum()
  577. {
  578.     if( head(Optr,"D" ))return(RD);
  579.     if( head(Optr,"d" ))return(RD);
  580.     if( head(Optr,"X" ))return(RX);
  581.     if( head(Optr,"x" ))return(RX);
  582.     if( head(Optr,"Y" ))return(RY);
  583.     if( head(Optr,"y" ))return(RY);
  584.     if( head(Optr,"U" ))return(RU);
  585.     if( head(Optr,"u" ))return(RU);
  586.     if( head(Optr,"S" ))return(RS);
  587.     if( head(Optr,"s" ))return(RS);
  588.     if( head(Optr,"PC" ))return(RPC);
  589.     if( head(Optr,"pc" ))return(RPC);
  590.     if( head(Optr,"PCR" ))return(RPCR);
  591.     if( head(Optr,"pcr" ))return(RPCR);
  592.     if( head(Optr,"A" ))return(RA);
  593.     if( head(Optr,"a" ))return(RA);
  594.     if( head(Optr,"B" ))return(RB);
  595.     if( head(Optr,"b" ))return(RB);
  596.     if( head(Optr,"CC" ))return(RCC);
  597.     if( head(Optr,"cc" ))return(RCC);
  598.     if( head(Optr,"DP" ))return(RDP);
  599.     if( head(Optr,"dp" ))return(RDP);
  600.     return(ERR);
  601. }
  602.  
  603.